﻿using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Mrsoft.Common;

namespace Mrsoft.Core
{
    class CoreManager
    {

        private Dictionary<int, DirectDealGame> cache;
        private bool running = false;

        public CoreManager(AadNewCoreIntoCacheEvent addEvent) {
            DirectDealGame.LsStateChangeEvent += DirectDealGameLsStateChangeEvent;
            DirectDealGame.QuitEvent += DirectDealGame_QuitEvent;
            DirectDealGame.SetShowEvent += DirectDealGameSetShow;
            this.addEvent = addEvent;
            cache = new Dictionary<int, DirectDealGame>();
            var task = new Task(Run);
            //task.ContinueWith(t => {
            //    if (t.IsFaulted)
            //        MsgListener.CommonMsgShow("监控系统", t.Exception.Message);
            //});
            task.Start();
        }

        #region DirectDealGame注册事件
        private void DirectDealGame_QuitEvent(int dwProcessId) {
            if (GameQuitNotifyEvent != null) {
                GameQuitNotifyEvent(dwProcessId);
                Shower = null;
                ConfigFactory.ClearDataBindings();
            }
        }

        private void DirectDealGameLsStateChangeEvent(int dwProcessId, string stateMsg, int index) {
            if (GameStateChangeNofifyEvent != null)
                GameStateChangeNofifyEvent(dwProcessId, stateMsg, index);
        }

        public void DirectDealGameSetShow(DirectDealGame core) {
            if (SetShowerEvent != null)
                SetShowerEvent(core);
        }
        #endregion

        #region 事件和委托
        public delegate void AadNewCoreIntoCacheEvent(string id, string name);
        private AadNewCoreIntoCacheEvent addEvent;
        public event DirectDealGame.SetShow SetShowerEvent;
        public event DirectDealGame.LsStateChange GameStateChangeNofifyEvent;
        public event DirectDealGame.QuitEventHandle GameQuitNotifyEvent;
        #endregion

        #region 监控部分
        private void Run() {
            running = true;
            DatiManager.Start();
            LoadData.FirstLoadData();//解析数据
            var games = new List<Process>();
            while (running) {
                Thread.Sleep(1000);
                if (GetGamesNotInCache(games)) {
                    if (!DirectDealGame.Data.IsReady) {
                        LoadData.LoadFromGame(games.First());
                    }
                    else {
                        foreach (var p in games) {
                            string name = NativeMethods.Rs(p.Id, DirectDealGame.Data.JS, DirectDealGame.Data.JS_OFF_1, DirectDealGame.Data.JS_OFF_2, DirectDealGame.Data.JS_OFF_3, DirectDealGame.Data.JS_NAME);
                            if (!string.IsNullOrEmpty(name)) {
                                AddIntoCache(p, name);
                                break;
                            }
                        }
                    }
                }
            }
        }

        private void AddIntoCache(Process p, string name) {
            if (addEvent != null) {
                addEvent(p.Id.ToString(), name);
            }
            var core = new DirectDealGame(p, name);
            cache.Add(p.Id, core);
        }




        private bool GetGamesNotInCache(List<Process> plist) {
            plist.Clear();
            var all = Process.GetProcessesByName("game");
            foreach (var process in all) {
                var isnew = true;
                foreach (var game in cache) {
                    if (game.Key == process.Id) {
                        isnew = false;
                        break;
                    }
                }
                if (isnew) {
                    plist.Add(process);
                }
            }
            return plist.Count > 0;
        }
        #endregion

        public DirectDealGame Shower { set; get; }

        public void Stop() {
            this.running = false;
            foreach (var c in cache) {
                c.Value.Close();
            }
        }

        public bool Remove(int pid, out DirectDealGame game) {
            if (cache.TryGetValue(pid, out game)) {
                cache.Remove(pid);
                if (game == Shower) {
                    if (cache.Count > 0)
                        Shower = cache.First().Value;
                    else
                        Shower = null;
                }
                return true;
            }
            return false;
        }

        public DirectDealGame GetByProcessId(int pid) {
            DirectDealGame game = null;
            cache.TryGetValue(pid, out game);
            return game;
        }
    }
}
